import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumnModel;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;

public class RecordsViewer {

    public static JFrame frame;
    private JTable table;
    private JTextArea textArea;
    private ArrayList<Records> recordsList;
    private RecordsTableModel tableModel;
    private JButton rollbackButton;

    //回溯的hash
    private String  willReturnHash = "";
    //回溯的文本
    private String  willReturnNote = "";
    //回溯的id
    private int willReturnId = -1;

    //head所在id
    private int headId = -1;

    //是否顶层显示
    private static boolean showTop = true;

    //自动隐藏

    private static final int HIDDEN_WIDTH = 20;  // 隐藏时的宽度
    private static final int TRIGGER_DISTANCE = 10;  // 触发隐藏的距离
    private boolean isHidden = false;
    private int mouseX, mouseY;

    //目标隐藏的x
    private int targetX = -594;
    private static Rectangle frameBounds = new Rectangle();

    private static boolean isMouseInFrame = false;
    private static final int POLLING_INTERVAL = 100; // 毫秒
    public RecordsViewer(ArrayList<Records> records) {
        recordsList = records;
        frame = new JFrame("Records Viewer");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 600);
        frame.setLayout(new BorderLayout());
        // 防止用户改变JFrame的大小
        frame.setResizable(false);
        // 获取屏幕尺寸
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        int screenWidth = screenSize.width;
        int screenHeight = screenSize.height;

        // 计算窗口位置，使其在屏幕正中间
        int windowWidth = frame.getWidth();
        int windowHeight = frame.getHeight();
        int windowX = (screenWidth - windowWidth) / 2;
        int windowY = (screenHeight - windowHeight) / 2;

        // 设置窗口位置
        frame.setLocation(targetX, windowY);

        //设置窗口自动托盘
        // 添加鼠标事件监听器
        // 添加鼠标事件监听器

        // 添加组件监听器以更新frameBounds
        frame.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentMoved(ComponentEvent e) {
                updateFrameBounds();
            }

            @Override
            public void componentResized(ComponentEvent e) {
                updateFrameBounds();
            }
        });

        // 添加全局鼠标监听器
        // 启动鼠标位置轮询线程
        // 真他娘的是个天才
        new Thread(() -> {
            while (true) {
                try {
                    Thread.sleep(POLLING_INTERVAL);
                    Point mouseLocation = MouseInfo.getPointerInfo().getLocation();
                    isMouseInFrame = frameBounds.contains(mouseLocation);

                    if (isMouseInFrame) {
                        frame.setLocation(0, frame.getY()); // 将X坐标设置为0
                        System.out.println("鼠标移入了");
                    } else {
                        frame.setLocation(-590, frame.getY()); // 将X坐标设置为-590
                        System.out.println("鼠标移出了");
                    }
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }).start();
        tableModel = new RecordsTableModel(recordsList);
        table = new JTable(tableModel);
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        table.setFont(new Font("Serif", Font.PLAIN, 16)); // 设置字体大小

        TableColumnModel columnModel = table.getColumnModel();
        columnModel.getColumn(0).setPreferredWidth(40);
        columnModel.getColumn(1).setPreferredWidth(200);
        columnModel.getColumn(2).setPreferredWidth(130);
        columnModel.getColumn(3).setPreferredWidth(20);

        table.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                int selectedRow = table.getSelectedRow();
                if (selectedRow >= 0) {
                    Records record = recordsList.get(selectedRow);

                    if (e.getClickCount() == 2) {
                        System.out.println("双击了记录: " + record.getHash());
                        GitUtil.go(record.getHash());
                        refreshTable();
                    } else {
                        textArea.setText(record.getHash());
                        System.out.println("点击了记录: " + record.getHash());
                        rollbackButton.setText("回溯到 " + record.getId() + " " + record.getNode());
                        willReturnHash = record.getHash();
                        willReturnNote = record.getNode();
                        willReturnId = record.getId();
                    }
                }
            }
        });

        textArea = new JTextArea();
        textArea.setEditable(false);
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        textArea.setFont(new Font("Serif", Font.PLAIN, 16)); // 设置字体大小

        frame.add(new JScrollPane(table), BorderLayout.CENTER);
        frame.add(new JScrollPane(textArea), BorderLayout.SOUTH);

        // 创建面板用于放置输入框和按钮
        JPanel bottomPanel = new JPanel(new BorderLayout());
        frame.add(bottomPanel, BorderLayout.SOUTH);

        // 创建标签和输入框
        JLabel label = new JLabel("存档备注:");
        label.setFont(new Font("Serif", Font.PLAIN, 16)); // 设置字体大小
        JTextField saveInfoField = new JTextField(20);
        saveInfoField.setFont(new Font("Serif", Font.PLAIN, 16)); // 设置字体大小

        // 将标签和输入框添加到面板的上部
        JPanel inputPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        inputPanel.add(label);
        inputPanel.add(saveInfoField);
        bottomPanel.add(inputPanel, BorderLayout.NORTH);

        frame.setAlwaysOnTop(true);

        // 创建按钮
        JButton saveButton = new JButton("存档");
        saveButton.setFont(new Font("Serif", Font.PLAIN, 16)); // 设置字体大小
        rollbackButton = new JButton("回溯");
        rollbackButton.setFont(new Font("Serif", Font.PLAIN, 16)); // 设置字体大小
        JButton destroyButton = new JButton("清除所有存档");
        destroyButton.setFont(new Font("Serif", Font.PLAIN, 16)); // 设置字体大小
        JButton topButton = new JButton("取消置顶");
        topButton.setFont(new Font("Serif", Font.PLAIN, 16)); // 设置字体大小
        topButton.addActionListener(e -> {
            showTop = !showTop;
            if (showTop) {
                topButton.setText("取消置顶");
                frame.setAlwaysOnTop(true);
            } else {
                topButton.setText("置顶");
                frame.setAlwaysOnTop(false);
            }
        });

        destroyButton.addActionListener(e -> {
            int result = showConfirmationDialog("确定要销毁所有存档吗?\n这不会改变当前文件夹的状态\n但是无法再次回到以前的存档\n这个行为不可逆");
            if (result == JOptionPane.YES_OPTION) {
                System.out.println("用户点击了确定按钮");
                GitUtil.deleteGit();
                refreshTable();
            }
        });

        saveButton.addActionListener(e -> {
            String saveInfo = saveInfoField.getText();
            System.out.println("存档信息: " + saveInfo);

            if (GitUtil.isGitRepository()) {
                int maxId = recordsList.get(0).getId();
                for (Records record : recordsList) {
                    if (record.getId() > maxId) {
                        maxId = record.getId();
                    }
                }
                if (maxId != headId) {
                    int i = showConfirmationDialog("当前不是处于顶端,无法进行存档\n当前点位执行过操作的无法保存\n如需保存请自行复制粘贴\n请前往顶端(这会丢失当前更改)\n");
                    return;
                }
            }

            GitUtil.commit(saveInfo);
            refreshTable();
        });

        rollbackButton.addActionListener(e -> {
            int result = showConfirmationDialog("确定要回溯到<" + willReturnNote + ">吗?\n这将会删除<"+willReturnNote+">之后的所有存档\n这个行为不可逆");
            if (result == JOptionPane.YES_OPTION) {
                System.out.println("执行回溯操作");
                GitUtil.backToRecord(willReturnHash);
                refreshTable();
            }
        });

        // 将按钮添加到面板的下部
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        buttonPanel.add(saveButton);
        buttonPanel.add(rollbackButton);
        buttonPanel.add(destroyButton);
        buttonPanel.add(topButton);
        bottomPanel.add(buttonPanel, BorderLayout.CENTER);

        frame.setVisible(true);
    }

    private static void updateFrameBounds() {
        frameBounds.setBounds(frame.getLocation().x, frame.getLocation().y, frame.getWidth(), frame.getHeight());
    }
    /**
     * 显示一个确认对话框，并返回用户的选择
     *
     * @param message 对话框中显示的消息
     * @return 用户点击的按钮，JOptionPane.YES_OPTION表示确定，JOptionPane.NO_OPTION表示取消
     */
    public static int showConfirmationDialog(String message) {
        //暂时取消置顶状态

        frame.setAlwaysOnTop(false);

        int result = JOptionPane.showConfirmDialog(
                null, // 父组件，null表示使用默认的框架作为父组件
                message, // 对话框中显示的消息
                "确认", // 对话框的标题
                JOptionPane.YES_NO_OPTION, // 对话框的选项（确定和取消）
                JOptionPane.WARNING_MESSAGE // 对话框的图标类型（警告）
        );

        if (showTop) {
            //topButton.setText("取消置顶");
            frame.setAlwaysOnTop(true);
        } else {
            //topButton.setText("置顶");
            frame.setAlwaysOnTop(false);
        }
        return result;
    }
    //刷新方法
    // 刷新方法
    public void refreshTable() {
        List<Records> newRecords = GitUtil.getCommitHistory();
        this.recordsList= (ArrayList<Records>) newRecords;
        if (tableModel != null) {
            tableModel.setRecords(newRecords);
        }
    }

    private class RecordsTableModel extends AbstractTableModel {
        private String[] columnNames = {"ID", "备注", "时间", "Hash"};
        private  List<Records> recordsList;

        public RecordsTableModel(ArrayList<Records> recordsList) {
            this.recordsList = recordsList;
        }

        @Override
        public int getRowCount() {
            return recordsList.size();
        }

        @Override
        public int getColumnCount() {
            return columnNames.length;
        }

        @Override
        public String getColumnName(int col) {
            return columnNames[col];
        }

        @Override
        public Object getValueAt(int row, int col) {
            Records record = recordsList.get(row);
            switch (col) {
                case 0:
                    if(record.isHead()){
                        headId=record.getId();
                    }
                    return record.getId()+(record.isHead()?"(当前)":"");
                case 1:
                    return record.getNode();
                case 2:
                    return record.getTime();
                case 3:
                    return record.getHash();
                default:
                    return null;
            }
        }

        public RecordsTableModel(List<Records> recordsList) {
            this.recordsList = recordsList;
        }

        // 添加一个方法来更新记录列表
        public void setRecords(List<Records> newRecords) {
            this.recordsList = newRecords;
            fireTableDataChanged(); // 通知表格数据已改变
        }

    }

    public static void main(String[] args) {
        //ArrayList<Records> records = new ArrayList<>();
        //records.add(new Records("hash1", "2023-10-01 12:00", 1, "NodeA"));
        //records.add(new Records("hash2", "2023-10-01 13:00", 2, "NodeB"));
        //records.add(new Records("hash3", "2023-10-01 14:00", 3, "NodeC"));

        while (true){
            try {
                List<Records> records = GitUtil.getCommitHistory();

                SwingUtilities.invokeLater(() -> new RecordsViewer((ArrayList<Records>) records));

            }catch (Exception e){
                //出现了异常,弹出提示
                int i = showConfirmationDialog("出现了异常,是否清空存档?\n此程序基于git开发\n存档任然可以通过专业手段找回\n点击确定清空存档");
                if(i==JOptionPane.YES_OPTION){
                    //删除.git文件夹和.myGitUtil文件
                    GitUtil.deleteGit();
                    continue;
                }else{
                    System.exit(0);
                }
            }
            break;
        }

    }
}